// This part of the code is based on the code given at the following URL:
//http://learningandroid.org/index.php?q=tutorial/2009/02/writing-sax-based-rss-and-podcast-parser#

package com.android.stockme.backend.fetcher;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class GoogleNewsManager extends DefaultHandler implements INewsManager
{
	
	
	private String urlString;
    private StringBuilder text;
    private INewsItem item;
    private List<INewsItem> newsItems;
    private boolean inChannel;
    private SimpleDateFormat formaterSrc;
    private SimpleDateFormat formaterDest;
    private String currSymbol;
    
    
    
	/**
     * The constructor for the RSS Parser
     * @param url
     */
    public GoogleNewsManager() 
    {
        this.item = null;
        this.urlString = null;
        this.newsItems = null;
        this.currSymbol = null;
        this.inChannel = false;
        this.text = new StringBuilder();
        this.formaterSrc  = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'");
        this.formaterDest  = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
    }//NewsManager
    
	
	public void run() {
		// TODO Auto-generated method stub

	}

	public List<INewsItem> fetchNewsUpdate(Collection<String> symbols)
	{
        this.item = null;
        this.urlString = null;
        this.newsItems = null;
        this.currSymbol = null;
        this.newsItems = new LinkedList<INewsItem>();
        this.inChannel = false;

        try {
			InetAddress.getAllByName("www.google.com");//check if we have connection
		} catch (UnknownHostException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return null;
		}//check if we have internet connection
		
        for (String symbol : symbols) 
        {
        	generateURL(symbol);
            this.currSymbol = symbol;
        	try {
				parse();
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}//for all symbols
        
        if (0 == this.newsItems.size())
        	return null;
        
		return this.newsItems;
	}//fetchNewsUpdate

   
    public void parse() throws ParserConfigurationException, SAXException, IOException, URISyntaxException 
    {
    	

        InputStream urlInputStream = null;
        SAXParserFactory spf = null;
        SAXParser sp = null;
        URL url = new URL(this.urlString);
        urlInputStream = url.openConnection().getInputStream();//establish connection    
        spf = SAXParserFactory.newInstance();
        if (spf != null) 
        {
            sp = spf.newSAXParser();
            sp.parse(urlInputStream, this);
        }
        if(urlInputStream != null)
    	{
        	urlInputStream.close();
    	}
        
    }//parse
    
    public void startElement(String uri, String localName, String qName, Attributes attributes) 
    {
        /** First lets check for the channel */
        if (localName.equalsIgnoreCase("channel")) 
        {
                this.inChannel = true;
        }
        
        /** Now lets check for an item */
        if (localName.equalsIgnoreCase("item") && (this.inChannel == true)) 
        {
            this.item = new NewsItem();
            this.item.setSymbol(this.currSymbol);
        }
		
    
    }//startElement
   
    /**
     * This is where we actually parse for the elements contents
     */
    public void endElement(String uri, String localName, String qName) 
    {
        /** Check we have an RSS Feed */
        if (this.inChannel == false) 
        {
            return;
        }
        
        /** Check if we are at the end of an item */
        if (localName.equalsIgnoreCase("item")) 
        {
        		this.newsItems.add(this.item);
                this.item = null;
        }
            

        if ((localName.equalsIgnoreCase("title")) && (this.item != null))
        {
            /** We are an item, so we set the item's title */
                this.item.setTitle(this.text.toString().trim());

        }       
       
        /** Now we are checking for a link **/
        if ((localName.equalsIgnoreCase("link")) && (this.item != null))
        {
			/** We are an item link, so we set the items link */
                this.item.setLink(this.text.toString().trim());

        }       
       
         /** Checking for an item's publish date **/
        if ((localName.equalsIgnoreCase("pubdate")) && (this.item != null)) 
        {
        	
        	String ourDateFormat = "";

    		try {
    			
    			ourDateFormat = formaterDest.format(formaterSrc.parse(this.text.toString().trim()));
    			this.item.setPublishDate(ourDateFormat);
    			
    		} catch (ParseException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}

        }       
        
        this.text.setLength(0);
        
    }//endElement
   
    
    public void characters(char[] ch, int start, int length) 
    {
        this.text.append(ch, start, length);
    }//characters
    
    
    public void generateURL(String ticker)
    {
    	this.urlString =  "http://www.google.com/finance?morenews=10&rating=1&q=" + ticker + "&output=rss";
    }//generateURL
  

}//GoogleNewsManager